home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / superopt.lha / superopt-2.2 / superopt.h < prev    next >
C/C++ Source or Header  |  1993-02-15  |  22KB  |  749 lines

  1. /* Superoptimizer definitions.
  2.  
  3.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  4.  
  5.    This program is free software; you can redistribute it and/or modify it
  6.    under the terms of the GNU General Public License as published by the
  7.    Free Software Foundation; either version 2, or (at your option) any
  8.    later version.
  9.  
  10.    This program is distributed in the hope that it will be useful, but
  11.    WITHOUT ANY WARRANTY; without even the implied warranty of
  12.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.    General Public License for more details.
  14.  
  15.    You should have received a copy of the GNU General Public License along
  16.    with this program; see the file COPYING.  If not, write to the Free
  17.    Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  18.  
  19. #if !(defined(SPARC) || defined(RS6000) || defined(M88000) \
  20.       || defined(AM29K) || defined(MC68000) || defined(MC68020) \
  21.       || defined(I386) || defined(PYR) || defined(ALPHA))
  22. /* If no target instruction set is defined, use host instruction set.  */
  23. #define SPARC (defined(sparc) || defined(__sparc__))
  24. #define RS6000 (defined(rs6000) || defined(_IBMR2))
  25. #define M88000 (defined(m88000) || defined(__m88000__))
  26. #define AM29K (defined(_AM29K) || defined(_AM29000))
  27. #define MC68020 (defined(m68020) || defined(mc68020))
  28. #define MC68000 (defined(m68000) || defined(mc68000))
  29. #define I386 (defined(i386) || defined(i80386))
  30. #define PYR (defined(pyr) || defined(__pyr__))
  31. #define ALPHA defined(__alpha)
  32. #endif
  33.  
  34. #define M68000 (MC68000 || MC68020)
  35.  
  36. #if !(SPARC || RS6000 || M88000 || AM29K || M68000 || I386 || PYR || ALPHA)
  37. You have to choose target CPU type (e.g. -DSPARC).
  38. #endif
  39.  
  40. #if MC68000
  41. #define SHIFT_COST(CNT) ((8+2*(CNT)) / 5) /* internal cost */
  42. #else
  43. #define SHIFT_COST(CNT) 1
  44. #endif
  45.  
  46. #ifndef USE_ASM
  47. #define NO_ASM 1
  48. #endif
  49.  
  50. #include "longlong.h"
  51.  
  52. #if ALPHA
  53. #define BITS_PER_WORD 64
  54. #else /* ! ALPHA */
  55. #define BITS_PER_WORD 32
  56. #endif
  57.  
  58. #if BITS_PER_WORD == 64
  59. #ifdef __GNUC__
  60. typedef unsigned long long int unsigned_word;
  61. typedef signed long long int signed_word;
  62. typedef unsigned_word word;
  63. #elif __alpha /* Native compiler on alpha has 64 bit longs.  */
  64. typedef unsigned long int unsigned_word;
  65. typedef signed long int signed_word;
  66. typedef unsigned_word word;
  67. #else /* Not on alpha, not GCC.  Don't have 64 bit type.  */
  68. #error Do not know how to perform 64 bit arithmetic with this compiler.
  69. #endif
  70. #else
  71. typedef unsigned int unsigned_word;
  72. typedef signed int signed_word;
  73. typedef unsigned_word word;
  74. #endif
  75.  
  76.  
  77. #define TRUNC_CNT(cnt) ((cnt) & (BITS_PER_WORD - 1))
  78.  
  79. #if defined(sparc) || defined(__GNUC__)
  80. #define alloca __builtin_alloca
  81. #endif
  82.  
  83. #if !defined(__GNUC__) || !defined(__OPTIMIZE__)
  84. #define inline /* Empty */
  85. #endif
  86.  
  87. /* The IMMEDIATE_* macros are for printing assembler.  NOT for sequence
  88.    generating or analyze.  */
  89. #define IMMEDIATE_P(op) (op >= 0x20 - 3)
  90. static const word __immediate_val[] =
  91. {
  92.   (word) 1 << (BITS_PER_WORD - 1),
  93.   ((word) 1 << (BITS_PER_WORD - 1)) - 1,
  94. };
  95. #define IMMEDIATE_VAL(op) \
  96.   ((op) >= 0x20 - 1 ? op - 0x20 : __immediate_val[0x20 - 2 - (op)])
  97.  
  98. /* Handle immediates by putting all handled values in the VALUE array at
  99.    appropriate indices, and then insert these indices in the code???
  100.    Interesting constants are probably 0, 1, -1, 0x80000000, and
  101.    0x7FFFFFFF.  */
  102.  
  103. #define CNST_0x80000000 (0x20 - 2)
  104. #define CNST_0x7FFFFFFF (0x20 - 3)
  105.  
  106. #define VALUE_MIN_SIGNED 0x80000000
  107. #define VALUE_MAX_SIGNED 0x7fffffff
  108.  
  109. #define CNST(n) (0x20 + n)
  110. #define VALUE(n) n
  111.  
  112. typedef enum
  113. {
  114. #undef DEF_INSN
  115. #define DEF_INSN(SYM,CLASS,NAME) SYM,
  116. #include "insn.def"
  117. } opcode_t;
  118.  
  119. #define GET_INSN_CLASS(OP) (insn_class[OP])
  120. #define GET_INSN_NAME(OP) (insn_name[OP])
  121.  
  122. #define UNARY_OPERATION(insn) (GET_INSN_CLASS (insn.opcode) == '1')
  123.  
  124. typedef struct
  125. {
  126.   opcode_t opcode:8;
  127.   unsigned int s1:8;
  128.   unsigned int s2:8;
  129.   unsigned int d:8;
  130. } insn_t;
  131.  
  132. #if __GNUC__ < 2
  133. #define __CLOBBER_CC
  134. #define __AND_CLOBBER_CC
  135. #else /* __GNUC__ >= 2 */
  136. #define __CLOBBER_CC : "cc"
  137. #define __AND_CLOBBER_CC , "cc"
  138. #endif /* __GNUC__ < 2 */
  139.  
  140. /* PERFORM_* for all instructions the search uses.  These macros are
  141.    used both in the search phase and in the test phase.  */
  142.  
  143. #if defined(__GNUC__) && defined(USE_ASM)
  144. /*** Define machine-dependent PERFORM_* here to improve synthesis speed ***/
  145.  
  146. #if sparc
  147. #define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
  148.   asm ("subcc %%g0,%4,%%g0    ! set cy if CI != 0
  149.     addxcc %2,%3,%0        ! add R1 and R2
  150.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  151.        : "=r" (d), "=r" (co)                        \
  152.        : "%r" (r1), "rI" (r2), "rI" (ci)                \
  153.        __CLOBBER_CC)
  154. #define PERFORM_ADD_CO(d, co, r1, r2, ci) \
  155.   asm ("addcc %2,%3,%0        ! add R1 and R2
  156.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  157.        : "=r" (d), "=r" (co)                        \
  158.        : "%r" (r1), "rI" (r2)                        \
  159.        __CLOBBER_CC)
  160. #define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
  161.   asm ("subcc %%g0,%4,%%g0    ! set cy if CI != 0
  162.     subxcc %2,%3,%0        ! subtract R2 from R1
  163.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  164.        : "=r" (d), "=r" (co)                        \
  165.        : "r" (r1), "rI" (r2), "rI" (ci)                    \
  166.        __CLOBBER_CC)
  167. #define PERFORM_SUB_CO(d, co, r1, r2, ci) \
  168.   asm ("subcc %2,%3,%0        ! subtract R2 from R1
  169.     addx %%g0,%%g0,%1    ! set CO to cy"                \
  170.        : "=r" (d), "=r" (co)                        \
  171.        : "r" (r1), "rI" (r2)                        \
  172.        __CLOBBER_CC)
  173. #define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
  174.   asm ("subcc %4,1,%%g0        ! cy = (CI == 0)
  175.     subxcc %2,%3,%0        ! subtract R2 from R1
  176.     subx %%g0,-1,%1        ! set CO to !cy"            \
  177.        : "=&r" (d), "=r" (co)                        \
  178.        : "r" (r1), "rI" (r2), "rI" (ci)                    \
  179.        __CLOBBER_CC)
  180. #define PERFORM_ADC_CO(d, co, r1, r2, ci) \
  181.   asm ("subcc %2,%3,%0        ! subtract R2 from R1
  182.     subx %%g0,-1,%1        ! set CO to !cy"            \
  183.        : "=&r" (d), "=r" (co)                        \
  184.        : "r" (r1), "rI" (r2)                        \
  185.        __CLOBBER_CC)
  186. #endif /* sparc */
  187.  
  188. #if m88k
  189. #define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
  190.   asm ("or %0,r0,1
  191.     subu.co r0,%4,%0    ; set cy if CI != 0
  192.     addu.cio %0,%2,%r3    ; add R1 and R2
  193.     addu.ci %1,r0,r0    ; set CO to cy"                \
  194.        : "=&r" (d), "=r" (co)                        \
  195.        : "%r" (r1), "Or" (r2), "r" (ci))
  196. #define PERFORM_ADD_CO(d, co, r1, r2, ci) \
  197.   asm ("addu.co %0,%2,%r3    ; add R1 and R2
  198.     addu.ci %1,r0,r0    ; set CO to cy"                \
  199.        : "=r" (d), "=r" (co)                        \
  200.        : "%r" (r1), "Or" (r2))
  201. #define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
  202.   asm ("subu.co r0,r0,%r4    ; reset cy if CI != 0
  203.     subu.cio %0,%2,%r3    ; subtract R2 from R1
  204.     subu.ci %1,r0,r0    ; set CO to -1+cy
  205.     subu %1,r0,%1        ; set CO to !cy"            \
  206.        : "=r" (d), "=r" (co)                        \
  207.        : "r" (r1), "Or" (r2), "Or" (ci))
  208. #define PERFORM_SUB_CO(d, co, r1, r2, ci) \
  209.   asm ("subu.co %0,%2,%r3    ; subtract R2 from R1
  210.     subu.ci %1,r0,r0    ; set CO to -1+cy
  211.     subu %1,r0,%1        ; set CO to !cy"            \
  212.        : "=r" (d), "=r" (co)                        \
  213.        : "r" (r1), "Or" (r2))
  214. #define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
  215.   asm ("or %0,r0,1
  216.     subu.co r0,%r4,%0    ; set cy if CI != 0
  217.     subu.cio %0,%2,%r3    ; subtract R2 from R1
  218.     addu.ci %1,r0,r0    ; set CO to cy"                \
  219.        : "=&r" (d), "=r" (co)                        \
  220.        : "r" (r1), "Or" (r2), "Or" (ci))
  221. #define PERFORM_ADC_CO(d, co, r1, r2, ci) \
  222.   asm ("subu.co %0,%2,%r3    ; subtract R2 from R1
  223.     addu.ci %1,r0,r0    ; set CO to cy"                \
  224.        : "=r" (d), "=r" (co)                        \
  225.        : "r" (r1), "Or" (r2))
  226. #endif /* m88k */
  227.  
  228. #endif /* __GNUC__ && USE_ASM*/
  229.  
  230. /************************* Default PERFORM_* in C *************************/
  231.  
  232. #define PERFORM_COPY(d, co, r1, ci) \
  233.   ((d) = (r1), (co) = (ci))
  234. #define PERFORM_EXCHANGE(co, r1, r2, ci) \
  235.   do {word __temp = (r1), (r1) = (r2), (r2) = __temp, (co) = (ci);} while (0)
  236.  
  237. #define PERFORM_ADD(d, co, r1, r2, ci) \
  238.   ((d) = (r1) + (r2), (co) = (ci))
  239. #ifndef PERFORM_ADD_CIO
  240. #define PERFORM_ADD_CIO(d, co, r1, r2, ci) \
  241.   do { word __d = (r1) + (ci);                        \
  242.        word __cy = __d < (ci);                        \
  243.        (d) = __d + (r2);                        \
  244.        (co) = ((d) < __d) + __cy; } while (0)
  245. #endif
  246. #ifndef PERFORM_ADD_CI
  247. #define PERFORM_ADD_CI(d, co, r1, r2, ci) \
  248.   do { word __d = (r1) + (r2) + (ci);                    \
  249.        (co) = (ci);                            \
  250.        (d) = __d; } while (0)
  251. #endif
  252. #ifndef PERFORM_ADD_CO
  253. #define PERFORM_ADD_CO(d, co, r1, r2, ci) \
  254.   do { word __d = (r1) + (r2);                        \
  255.        (co) = __d < (r1);                        \
  256.        (d) = __d; } while (0)
  257. #endif
  258.  
  259. #define PERFORM_SUB(d, co, r1, r2, ci) \
  260.   ((d) = (r1) - (r2), (co) = (ci))
  261. #ifndef PERFORM_SUB_CIO
  262. #define PERFORM_SUB_CIO(d, co, r1, r2, ci) \
  263.   do { word __d = (r1) - (r2) - (ci);                    \
  264.        (co) = (ci) ? __d >= (r1) : __d > (r1);                \
  265.        (d) = __d; } while (0)
  266. #endif
  267. #ifndef PERFORM_SUB_CI
  268. #define PERFORM_SUB_CI(d, co, r1, r2, ci) \
  269.   do { word __d = (r1) - (r2) - (ci);                    \
  270.        (co) = (ci);                            \
  271.        (d) = __d; } while (0)
  272. #endif
  273. #ifndef PERFORM_SUB_CO
  274. #define PERFORM_SUB_CO(d, co, r1, r2, ci) \
  275.   do { word __d = (r1) - (r2);                        \
  276.        (co) = __d > (r1);                        \
  277.        (d) = __d; } while (0)
  278. #endif
  279.  
  280. #ifndef PERFORM_ADC_CIO
  281. #define PERFORM_ADC_CIO(d, co, r1, r2, ci) \
  282.   do { word __d = (r1) + ~(r2) + (ci);                    \
  283.        (co) = (ci) ? __d <= (r1) : __d < (r1);                \
  284.        (d) = __d; } while (0)
  285. #endif
  286. #ifndef PERFORM_ADC_CI
  287. #define PERFORM_ADC_CI(d, co, r1, r2, ci) \
  288.   do { word __d = (r1) + ~(r2) + (ci);                    \
  289.        (co) = (ci);                            \
  290.        (d) = __d; } while (0)
  291. #endif
  292. #ifndef PERFORM_ADC_CO
  293. #define PERFORM_ADC_CO(d, co, r1, r2, ci) \
  294.   do { word __d = (r1) - (r2);                        \
  295.        (co) = __d <= (r1);                        \
  296.        (d) = __d; } while (0)
  297. #endif
  298.  
  299. #ifndef PERFORM_CMP
  300. #define PERFORM_CMP(d, co, r1, r2, ci) \
  301.   ((co) = (r1) < (r2))
  302. #endif
  303. #ifndef PERFORM_CMPPAR
  304. #define PERFORM_CMPPAR(d, co, r1, r2, ci) \
  305.   do {                                    \
  306.     word __x;                                \
  307.     union { long w; short h[2]; char b[4]; } __r1, __r2;        \
  308.     __r1.w = (r1); __r2.w = (r2);                    \
  309.     __x = ((__r1.h[0] != __r2.h[0]) && (__r1.h[1] != __r2.h[1])) << 14;    \
  310.     __x |= ((__r1.b[0] != __r2.b[0]) && (__r1.b[1] != __r2.b[1])    \
  311.        && (__r1.b[2] != __r2.b[2]) && (__r1.b[3] != __r2.b[3])) << 12; \
  312.     __x |= ((unsigned_word) (r1) >= (unsigned_word) (r2)) << 10;    \
  313.     __x |= ((unsigned_word) (r1) <= (unsigned_word) (r2)) << 8;        \
  314.     __x |= ((signed_word) (r1) >= (signed_word) (r2)) << 6;        \
  315.     __x |= ((signed_word) (r1) <= (signed_word) (r2)) << 4;        \
  316.     __x |= ((r1) != (r2)) << 2;                        \
  317.     (d) = __x + 0x5554;        /* binary 0101010101010100 */        \
  318.     (co) = (ci);                            \
  319.   } while (0)
  320. #endif
  321.  
  322. /* Logic operations that don't affect carry.  */
  323. #ifndef PERFORM_AND
  324. #define PERFORM_AND(d, co, r1, r2, ci) \
  325.   ((d) = (r1) & (r2), (co) = (ci))
  326. #endif
  327. #ifndef PERFORM_IOR
  328. #define PERFORM_IOR(d, co, r1, r2, ci) \
  329.   ((d) = (r1) | (r2), (co) = (ci))
  330. #endif
  331. #ifndef PERFORM_XOR
  332. #define PERFORM_XOR(d, co, r1, r2, ci) \
  333.   ((d) = (r1) ^ (r2), (co) = (ci))
  334. #endif
  335. #ifndef PERFORM_ANDC
  336. #define PERFORM_ANDC(d, co, r1, r2, ci) \
  337.   ((d) = (r1) & ~(r2), (co) = (ci))
  338. #endif
  339. #ifndef PERFORM_IORC
  340. #define PERFORM_IORC(d, co, r1, r2, ci) \
  341.   ((d) = (r1) | ~(r2), (co) = (ci))
  342. #endif
  343. #ifndef PERFORM_EQV
  344. #define PERFORM_EQV(d, co, r1, r2, ci) \
  345.   ((d) = (r1) ^ ~(r2), (co) = (ci))
  346. #endif
  347. #ifndef PERFORM_NAND
  348. #define PERFORM_NAND(d, co, r1, r2, ci) \
  349.   ((d) = ~((r1) & (r2)), (co) = (ci))
  350. #endif
  351. #ifndef PERFORM_NOR
  352. #define PERFORM_NOR(d, co, r1, r2, ci) \
  353.   ((d) = ~((r1) | (r2)), (co) = (ci))
  354. #endif
  355.  
  356. /* Logic operations that reset carry.  */
  357. #ifndef PERFORM_AND_RC
  358. #define PERFORM_AND_RC(d, co, r1, r2, ci) \
  359.   ((d) = (r1) & (r2), (co) = 0)
  360. #endif
  361. #ifndef PERFORM_IOR_RC
  362. #define PERFORM_IOR_RC(d, co, r1, r2, ci) \
  363.   ((d) = (r1) | (r2), (co) = 0)
  364. #endif
  365. #ifndef PERFORM_XOR_RC
  366. #define PERFORM_XOR_RC(d, co, r1, r2, ci) \
  367.   ((d) = (r1) ^ (r2), (co) = 0)
  368. #endif
  369. #ifndef PERFORM_ANDC_RC
  370. #define PERFORM_ANDC_RC(d, co, r1, r2, ci) \
  371.   ((d) = (r1) & ~(r2), (co) = 0)
  372. #endif
  373. #ifndef PERFORM_IORC_RC
  374. #define PERFORM_IORC_RC(d, co, r1, r2, ci) \
  375.   ((d) = (r1) | ~(r2), (co) = 0)
  376. #endif
  377. #ifndef PERFORM_EQV_RC
  378. #define PERFORM_EQV_RC(d, co, r1, r2, ci) \
  379.   ((d) = (r1) ^ ~(r2), (co) = 0)
  380. #endif
  381. #ifndef PERFORM_NAND_RC
  382. #define PERFORM_NAND_RC(d, co, r1, r2, ci) \
  383.   ((d) = ~((r1) & (r2)), (co) = 0)
  384. #endif
  385. #ifndef PERFORM_NOR_RC
  386. #define PERFORM_NOR_RC(d, co, r1, r2, ci) \
  387.   ((d) = ~((r1) | (r2)), (co) = 0)
  388. #endif
  389.  
  390. /* Logic operations that clobber carry.  */
  391. #ifndef PERFORM_AND_CC
  392. #define PERFORM_AND_CC(d, co, r1, r2, ci) \
  393.   ((d) = (r1) & (r2), (co) = -1)
  394. #endif
  395. #ifndef PERFORM_IOR_CC
  396. #define PERFORM_IOR_CC(d, co, r1, r2, ci) \
  397.   ((d) = (r1) | (r2), (co) = -1)
  398. #endif
  399. #ifndef PERFORM_XOR_CC
  400. #define PERFORM_XOR_CC(d, co, r1, r2, ci) \
  401.   ((d) = (r1) ^ (r2), (co) = -1)
  402. #endif
  403. #ifndef PERFORM_ANDC_CC
  404. #define PERFORM_ANDC_CC(d, co, r1, r2, ci) \
  405.   ((d) = (r1) & ~(r2), (co) = -1)
  406. #endif
  407. #ifndef PERFORM_IORC_CC
  408. #define PERFORM_IORC_CC(d, co, r1, r2, ci) \
  409.   ((d) = (r1) | ~(r2), (co) = -1)
  410. #endif
  411. #ifndef PERFORM_EQV_CC
  412. #define PERFORM_EQV_CC(d, co, r1, r2, ci) \
  413.   ((d) = (r1) ^ ~(r2), (co) = -1)
  414. #endif
  415. #ifndef PERFORM_NAND_CC
  416. #define PERFORM_NAND_CC(d, co, r1, r2, ci) \
  417.   ((d) = ~((r1) & (r2)), (co) = -1)
  418. #endif
  419. #ifndef PERFORM_NOR_CC
  420. #define PERFORM_NOR_CC(d, co, r1, r2, ci) \
  421.   ((d) = ~((r1) | (r2)), (co) = -1)
  422. #endif
  423.  
  424. #ifndef PERFORM_LSHIFTR
  425. #define PERFORM_LSHIFTR(d, co, r1, r2, ci) \
  426.   ((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)),            \
  427.    (co) = (ci))
  428. #endif
  429. #ifndef PERFORM_ASHIFTR
  430. #define PERFORM_ASHIFTR(d, co, r1, r2, ci) \
  431.   ((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)),                \
  432.    (co) = (ci))
  433. #endif
  434. #ifndef PERFORM_SHIFTL
  435. #define PERFORM_SHIFTL(d, co, r1, r2, ci) \
  436.   ((d) = ((signed_word) (r1) << TRUNC_CNT(r2)), (co) = (ci))
  437. #endif
  438. #ifndef PERFORM_ROTATEL
  439. #define PERFORM_ROTATEL(d, co, r1, r2, ci) \
  440.  ((d) = (r2) == 0 ? (r1)                        \
  441.   : ((r1) << TRUNC_CNT(r2)) | ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))),\
  442.   (co) = (ci))
  443. #endif
  444. #ifndef PERFORM_LSHIFTR_CO
  445. #define PERFORM_LSHIFTR_CO(d, co, r1, r2, ci) \
  446.   do { word __d = ((unsigned_word) (r1) >> TRUNC_CNT(r2));        \
  447.        (co) = ((unsigned_word) (r1) >> (TRUNC_CNT(r2) - 1)) & 1;    \
  448.        (d) = __d; } while (0)
  449. #endif
  450. #ifndef PERFORM_ASHIFTR_CO
  451. #define PERFORM_ASHIFTR_CO(d, co, r1, r2, ci) \
  452.   do { word __d = ((signed_word) (r1) >> TRUNC_CNT(r2));        \
  453.        (co) = ((signed_word) (r1) >> (TRUNC_CNT(r2) - 1)) & 1;        \
  454.        (d) = __d; } while (0)
  455. #endif
  456. #ifndef PERFORM_ASHIFTR_CON
  457. #define PERFORM_ASHIFTR_CON(d, co, r1, r2, ci) \
  458.   do { word __d = ((signed_word) (r1) >> TRUNC_CNT(r2));        \
  459.      (co) = (signed_word) (r1) < 0                    \
  460.        && ((r1) << TRUNC_CNT(BITS_PER_WORD - (r2))) != 0;        \
  461.        (d) = __d; } while (0)
  462. #endif
  463. #ifndef PERFORM_SHIFTL_CO
  464. #define PERFORM_SHIFTL_CO(d, co, r1, r2, ci) \
  465.   do { word __d = ((signed_word) (r1) << TRUNC_CNT(r2));        \
  466.        (co) = ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))) & 1;        \
  467.        (d) = __d; } while (0)
  468. #endif
  469. #ifndef PERFORM_ROTATEL_CO
  470. #define PERFORM_ROTATEL_CO(d, co, r1, r2, ci) \
  471.   ((d) = ((r1) << TRUNC_CNT(r2)) | ((r1) >> TRUNC_CNT(BITS_PER_WORD - (r2))),\
  472.    (co) = (d) & 1)
  473. #endif
  474. #ifndef PERFORM_ROTATEXL_CIO
  475. #define PERFORM_ROTATEXL_CIO(d, co, r1, r2, ci) \
  476.   do { word __d;  unsigned cnt = TRUNC_CNT(r2);                \
  477.        if (cnt == 1)                            \
  478.      {                                \
  479.        __d = ((r1) << 1) | (ci);                    \
  480.        (co) = (r1) >> (BITS_PER_WORD - 1);                \
  481.      }                                \
  482.        else                                \
  483.      {                                \
  484.        __d = ((r1) << cnt)                        \
  485.          | (ci) << (cnt - 1)                    \
  486.          | ((r1) >> (BITS_PER_WORD + 1 - cnt));            \
  487.        (co) = ((r1) >> (BITS_PER_WORD - cnt)) & 1;            \
  488.      }                                \
  489.        (d) = __d;                            \
  490.      } while (0)
  491. #endif
  492. #ifndef PERFORM_EXTS1
  493. #define PERFORM_EXTS1(d, co, r1, r2, ci) \
  494.   ((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)) << 31 >> 31, (co) = (ci))
  495. #endif
  496. #ifndef PERFORM_EXTS2
  497. #define PERFORM_EXTS2(d, co, r1, r2, ci) \
  498.   ((d) = ((signed_word) (r1) >> TRUNC_CNT(r2)) << 30 >> 30, (co) = (ci))
  499. #endif
  500. #ifndef PERFORM_EXTU1
  501. #define PERFORM_EXTU1(d, co, r1, r2, ci) \
  502.   ((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)) & 1, (co) = (ci))
  503. #endif
  504. #ifndef PERFORM_EXTU2
  505. #define PERFORM_EXTU2(d, co, r1, r2, ci) \
  506.   ((d) = ((unsigned_word) (r1) >> TRUNC_CNT(r2)) & 3, (co) = (ci))
  507. #endif
  508.  
  509. #ifndef PERFORM_DOZ
  510. #define PERFORM_DOZ(d, co, r1, r2, ci) \
  511.   (((d) = (signed_word) (r1) > (signed_word) (r2) ? (r1) - (r2) : 0),    \
  512.    (co) = (ci))
  513. #endif
  514.  
  515. #ifndef PERFORM_CPEQ
  516. #define PERFORM_CPEQ(d, co, r1, r2, ci) \
  517.   ((d) = ((r1) == (r2)) << 31, (co) = (ci))
  518. #endif
  519. #ifndef PERFORM_CPGE
  520. #define PERFORM_CPGE(d, co, r1, r2, ci) \
  521.   ((d) = ((signed_word) (r1) >= (signed_word) (r2)) << 31, (co) = (ci))
  522. #endif
  523. #ifndef PERFORM_CPGEU
  524. #define PERFORM_CPGEU(d, co, r1, r2, ci) \
  525.   ((d) = ((unsigned_word) (r1) >= (unsigned_word) (r2)) << 31, (co) = (ci))
  526. #endif
  527. #ifndef PERFORM_CPGT
  528. #define PERFORM_CPGT(d, co, r1, r2, ci) \
  529.   ((d) = ((signed_word) (r1) > (signed_word) (r2)) << 31, (co) = (ci))
  530. #endif
  531. #ifndef PERFORM_CPGTU
  532. #define PERFORM_CPGTU(d, co, r1, r2, ci) \
  533.   ((d) = ((unsigned_word) (r1) > (unsigned_word) (r2)) << 31, (co) = (ci))
  534. #endif
  535. #ifndef PERFORM_CPLE
  536. #define PERFORM_CPLE(d, co, r1, r2, ci) \
  537.   ((d) = ((signed_word) (r1) <= (signed_word) (r2)) << 31, (co) = (ci))
  538. #endif
  539. #ifndef PERFORM_CPLEU
  540. #define PERFORM_CPLEU(d, co, r1, r2, ci) \
  541.   ((d) = ((unsigned_word) (r1) <= (unsigned_word) (r2)) << 31, (co) = (ci))
  542. #endif
  543. #ifndef PERFORM_CPLT
  544. #define PERFORM_CPLT(d, co, r1, r2, ci) \
  545.   ((d) = ((signed_word) (r1) < (signed_word) (r2)) << 31, (co) = (ci))
  546. #endif
  547. #ifndef PERFORM_CPLTU
  548. #define PERFORM_CPLTU(d, co, r1, r2, ci) \
  549.   ((d) = ((unsigned_word) (r1) < (unsigned_word) (r2)) << 31, (co) = (ci))
  550. #endif
  551. #ifndef PERFORM_CPNEQ
  552. #define PERFORM_CPNEQ(d, co, r1, r2, ci) \
  553.   ((d) = ((r1) != (r2)) << 31, (co) = (ci))
  554. #endif
  555.  
  556. #ifndef PERFORM_CMPEQ
  557. #define PERFORM_CMPEQ(d, co, r1, r2, ci) \
  558.   ((d) = (r1) == (r2), (co) = (ci))
  559. #endif
  560. #ifndef PERFORM_CMPLE
  561. #define PERFORM_CMPLE(d, co, r1, r2, ci) \
  562.   ((d) = (signed_word) (r1) <= (signed_word) (r2), (co) = (ci))
  563. #endif
  564. #ifndef PERFORM_CMPLEU
  565. #define PERFORM_CMPLEU(d, co, r1, r2, ci) \
  566.   ((d) = (unsigned_word) (r1) <= (unsigned_word) (r2), (co) = (ci))
  567. #endif
  568. #ifndef PERFORM_CMPLT
  569. #define PERFORM_CMPLT(d, co, r1, r2, ci) \
  570.   ((d) = (signed_word) (r1) < (signed_word) (r2), (co) = (ci))
  571. #endif
  572. #ifndef PERFORM_CMPLTU
  573. #define PERFORM_CMPLTU(d, co, r1, r2, ci) \
  574.   ((d) = (unsigned_word) (r1) < (unsigned_word) (r2), (co) = (ci))
  575. #endif
  576.  
  577. /* Unary operations.  */
  578. #ifndef PERFORM_CLZ
  579. #define PERFORM_CLZ(d, co, r1, ci) \
  580.   do {                                    \
  581.     int __a;                                \
  582.     __a = (r1) <= 0xffff                        \
  583.       ? ((r1) <= 0xff ? 0 : 8)                        \
  584.       : ((r1) <= 0xffffff ?  16 : 24);                    \
  585.     (d) = clz_tab[(r1) >> __a] - __a;                    \
  586.     (co) = (ci);                            \
  587.   } while (0)
  588. #endif
  589. #ifndef PERFORM_CTZ
  590. /* This can be done faster using the (x & -x) trick.  */
  591. #define PERFORM_CTZ(d, co, r1, ci) \
  592.   do {                                    \
  593.     int __a;                                \
  594.     __a = ((r1) & 0xffff == 0)                        \
  595.       ? (((r1) & 0xff0000) == 0 ? 24 : 16)                \
  596.       : ((r1) & 0xff == 0) ? 8 : 0;                    \
  597.     (d) = ctz_tab[((r1) >> __a) & 0xff] + __a;                \
  598.     (co) = (ci);                            \
  599.   } while (0)
  600. #endif
  601. #ifndef PERFORM_FF1
  602. #define PERFORM_FF1(d, co, r1, ci) \
  603.   do {                                    \
  604.     int __a;                                \
  605.     __a = (r1) <= 0xffff                        \
  606.       ? ((r1) <= 0xff ? 0 : 8)                        \
  607.       : ((r1) <= 0xffffff ?  16 : 24);                    \
  608.     (d) = ff1_tab[(r1) >> __a] + __a;                    \
  609.     (co) = (ci);                            \
  610.     FF1_CHECK(d,r1)                            \
  611.   } while (0)
  612. #endif
  613. #if m88k
  614. #define FF1_CHECK(d,r1)                            \
  615.   { int t;                                \
  616.     asm ("ff1 %0,%1" : "=r" (t) : "r" (r1));                \
  617.     if (t != (d)) abort (); }
  618. #else
  619. #define FF1_CHECK(d,r1)
  620. #endif
  621. #ifndef PERFORM_FF0
  622. #define PERFORM_FF0(d, co, r1, ci) \
  623.   PERFORM_FF1(d, co, ~(r1), ci)
  624. #endif
  625. #ifndef PERFORM_FFS
  626. #define PERFORM_FFS(d, co, r1, ci) \
  627.   do {                                    \
  628.     int __a;                                \
  629.     word __x = (r1) & (-r1);                        \
  630.     PERFORM_CLZ(d, co, __x, ci);                    \
  631.     (d) = 32 - (d);                            \
  632.   } while (0)
  633. #endif
  634. #ifndef PERFORM_ABSVAL
  635. #define PERFORM_ABSVAL(d, co, r1, ci) \
  636.   ((d) = (signed_word) (r1) < 0 ? -(r1) : (r1), (co) = (ci))
  637. #endif
  638. #ifndef PERFORM_NABSVAL
  639. #define PERFORM_NABSVAL(d, co, r1, ci) \
  640.   ((d) = (signed_word) (r1) > 0 ? -(r1) : (r1), (co) = (ci))
  641. #endif
  642.  
  643. #ifndef PERFORM_CMOVEQ
  644. #define PERFORM_CMOVEQ(d, co, r1, r2, ci) \
  645.   ((d) = (r1) == 0 ? (r2) : (d), (co) = (ci))
  646. #endif
  647. #ifndef PERFORM_CMOVNE
  648. #define PERFORM_CMOVNE(d, co, r1, r2, ci) \
  649.   ((d) = (r1) != 0 ? (r2) : (d), (co) = (ci))
  650. #endif
  651. #ifndef PERFORM_CMOVLT
  652. #define PERFORM_CMOVLT(d, co, r1, r2, ci) \
  653.   ((d) = (signed_word) (r1) < 0 ? (r2) : (d), (co) = (ci))
  654. #endif
  655. #ifndef PERFORM_CMOVGE
  656. #define PERFORM_CMOVGE(d, co, r1, r2, ci) \
  657.   ((d) = (signed_word) (r1) >= 0 ? (r2) : (d), (co) = (ci))
  658. #endif
  659. #ifndef PERFORM_CMOVLE
  660. #define PERFORM_CMOVLE(d, co, r1, r2, ci) \
  661.   ((d) = (signed_word) (r1) <= 0 ? (r2) : (d), (co) = (ci))
  662. #endif
  663. #ifndef PERFORM_CMOVGT
  664. #define PERFORM_CMOVGT(d, co, r1, r2, ci) \
  665.   ((d) = (signed_word) (r1) > 0 ? (r2) : (d), (co) = (ci))
  666. #endif
  667.  
  668. #ifndef PERFORM_INVDIV
  669. #define PERFORM_INVDIV(v, co, r1, ci) \
  670.   do {                                    \
  671.     word __q, __r;                            \
  672.     udiv_qrnnd (__q, __r, -(r1), 0, (r1));                \
  673.     (v) = __q;                                \
  674.     (co) = (ci);                            \
  675.   } while (0)
  676. #endif
  677. #ifndef PERFORM_INVMOD
  678. #define PERFORM_INVMOD(v, co, r1, ci) \
  679.   do {                                    \
  680.     word __q, __r;                            \
  681.     udiv_qrnnd (__q, __r, -(r1), 0, (r1));                \
  682.     (v) = __r;                                \
  683.     (co) = (ci);                            \
  684.   } while (0)
  685. #endif
  686. #ifndef PERFORM_MUL
  687. #define PERFORM_MUL(v, co, r1, r2, ci) \
  688.   do {                                    \
  689.     (v) = (r1) * (r2);                            \
  690.     (co) = (ci);                            \
  691.   } while (0)
  692. #endif
  693. #ifndef PERFORM_UMULWIDEN_HI
  694. #define PERFORM_UMULWIDEN_HI(v, co, r1, r2, ci) \
  695.   do {                                    \
  696.     word __ph, __pl;                            \
  697.     umul_ppmm (__ph, __pl, (r1), (r2));                    \
  698.     (v) = __ph;                                \
  699.     (co) = (ci);                            \
  700.   } while (0)
  701. #endif
  702.  
  703. #ifdef UDIV_WITH_SDIV
  704. #define PERFORM_SDIV(v, co, r1, r2, ci) \
  705.   do {                                    \
  706.     if ((r2) != 0)                            \
  707.       (v) = (signed_word) (r1) / (signed_word) (r2);            \
  708.     else                                \
  709.       (v) = 0;                                \
  710.     (co) = (ci);                            \
  711.     } while (0)
  712. #endif /* UDIV_WITH_SDIV */
  713.  
  714. enum goal_func
  715. {
  716. #undef    DEF_GOAL
  717. #define DEF_GOAL(SYM,ARITY,NAME,CODE) SYM,
  718. #undef    DEF_SYNONYM
  719. #define DEF_SYNONYM(SYM,NAME)
  720. #include "goal.def"
  721.   LAST_AND_UNUSED_GOAL_CODE
  722. };
  723.  
  724. enum prune_flags
  725. {
  726.   NO_PRUNE = 0,
  727.   CY_0 = 1,
  728.   CY_1 = 2,
  729.   CY_JUST_SET = 4,
  730. };
  731.  
  732. void
  733. synth(insn_t *sequence,
  734.       int n_insns,
  735.       word *values,
  736.       int n_values,
  737.       word desired_value,
  738.       int allowed_cost,
  739.       int cy_in,
  740.       int flags);
  741. void
  742. test_sequence(insn_t *sequence, int n_insns);
  743. int
  744. run_program(insn_t *sequence, int n_insns, word *values);
  745.  
  746. extern const char clz_tab[];
  747. extern const char ctz_tab[];
  748. extern const char ff1_tab[];
  749.